package znet

import (
	"fmt"
	"zinx-learn/utils"
	"zinx-learn/ziface"
)

type MsgHandler struct {
	Apis         map[uint32]ziface.IRouter
	WorkPoolSize uint32
	TaskQueue    []chan ziface.IRequest
}

func (m *MsgHandler) StartOneWork(id int, requestChan chan ziface.IRequest) {
	fmt.Printf("<start work ID=%d>\n", id)
	for {
		select {
		case request := <-requestChan:
			m.DoMsgHandler(request)
		}
	}
}

func (m *MsgHandler) StartWorkerPool() {
	for i := 0; i < int(m.WorkPoolSize); i++ {
		m.TaskQueue[i] = make(chan ziface.IRequest, utils.GlobalObject.MaxWorkTaskLen)
		go m.StartOneWork(i, m.TaskQueue[i])
	}
}

func (m *MsgHandler) SendMsgToTaskQueue(request ziface.IRequest) {
	id := request.GetConnection().GetConnectionID()
	index := id % m.WorkPoolSize
	fmt.Printf("Add connection ID =%d request msgId = %d\n", id, request.GetMessageID())
	m.TaskQueue[index] <- request
}

func (m *MsgHandler) DoMsgHandler(request ziface.IRequest) {
	id := request.GetMessageID()
	router, ok := m.Apis[id]
	// 没有找到对应的处理的方法
	if !ok {
		// 调用默认的baseRouter的NotFoundHandler进行处理
		baseRouter := &BaseRouter{}
		baseRouter.NotFoundHandler(request)
		fmt.Printf("id = %d router not found \n", id)
		return
	}
	router.PreHandle(request)
	router.Handle(request)
	router.PostHandle(request)
}

func (m *MsgHandler) AddRouter(msgId uint32, router ziface.IRouter) {
	// 查询该ID的方法是否已经被定义了
	if _, ok := m.Apis[msgId]; ok {
		// 引发错误 退出程序
		panic(fmt.Sprintf("msgId = %d has already defined !", msgId))
	}
	m.Apis[msgId] = router
	fmt.Println("add router success !")
}

func NewMsgHandler() *MsgHandler {

	return &MsgHandler{
		Apis:         map[uint32]ziface.IRouter{},
		WorkPoolSize: utils.GlobalObject.WorkPoolSize,
		TaskQueue:    make([]chan ziface.IRequest, utils.GlobalObject.WorkPoolSize),
	}
}
